<!DOCTYPE html>
<html class="writer-html5" lang="en" data-content_root="../">
<head>
  <meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" />

  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>linter &mdash; The Logtalk Handbook v3.93.0-b01 documentation</title>
      <link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=d75fae25" />
      <link rel="stylesheet" type="text/css" href="../_static/css/theme.css?v=19f00094" />
      <link rel="stylesheet" type="text/css" href="../_static/css/custom.css?v=396eccfe" />

  
  <!--[if lt IE 9]>
    <script src="../_static/js/html5shiv.min.js"></script>
  <![endif]-->
  
        <script src="../_static/jquery.js?v=5d32c60e"></script>
        <script src="../_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
        <script src="../_static/documentation_options.js?v=c8100655"></script>
        <script src="../_static/doctools.js?v=9a2dae69"></script>
        <script src="../_static/sphinx_highlight.js?v=dc90522c"></script>
    <script src="../_static/js/theme.js"></script>
    <!-- begin favicon -->
    <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
    <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
    <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
    <link rel="manifest" href="/site.webmanifest" />
    <link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5" />
    <meta name="msapplication-TileColor" content="#355b95" />
    <meta name="theme-color" content="#ffffff" />
    <!-- end favicon -->
    
    <link rel="index" title="Index" href="../genindex.html" />
    <link rel="search" title="Search" href="../search.html" />
    <link rel="next" title="make" href="make.html" />
    <link rel="prev" title="lgtunit" href="lgtunit.html" />
   
</head>

<body class="wy-body-for-nav"> 
  <div class="wy-grid-for-nav">
    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
      <div class="wy-side-scroll">
        <div class="wy-side-nav-search" >

          
          
          <a href="../index.html" class="icon icon-home">
            The Logtalk Handbook
              <img src="../_static/logtalk.gif" class="logo" alt="Logo"/>
          </a>
              <div class="version">
                3.93.0
              </div>
<div role="search">
  <form id="rtd-search-form" class="wy-form" action="../search.html" method="get">
    <input type="text" name="q" placeholder="Search docs" aria-label="Search docs" />
    <input type="hidden" name="check_keywords" value="yes" />
    <input type="hidden" name="area" value="default" />
  </form>
</div>
        </div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
    
              <p class="caption" role="heading"><span class="caption-text">Contents</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../userman/index.html">User Manual</a></li>
<li class="toctree-l1"><a class="reference internal" href="../refman/index.html">Reference Manual</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tutorial/index.html">Tutorial</a></li>
<li class="toctree-l1"><a class="reference internal" href="../faq/index.html">FAQ</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="index.html">Developer Tools</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="overview.html">Overview</a></li>
<li class="toctree-l2"><a class="reference internal" href="asdf.html"><code class="docutils literal notranslate"><span class="pre">asdf</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="assertions.html"><code class="docutils literal notranslate"><span class="pre">assertions</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="code_metrics.html"><code class="docutils literal notranslate"><span class="pre">code_metrics</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="dead_code_scanner.html"><code class="docutils literal notranslate"><span class="pre">dead_code_scanner</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="debug_messages.html"><code class="docutils literal notranslate"><span class="pre">debug_messages</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="debugger.html"><code class="docutils literal notranslate"><span class="pre">debugger</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="diagrams.html"><code class="docutils literal notranslate"><span class="pre">diagrams</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="doclet.html"><code class="docutils literal notranslate"><span class="pre">doclet</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="help.html"><code class="docutils literal notranslate"><span class="pre">help</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="issue_creator.html"><code class="docutils literal notranslate"><span class="pre">issue_creator</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="lgtdoc.html"><code class="docutils literal notranslate"><span class="pre">lgtdoc</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="lgtunit.html"><code class="docutils literal notranslate"><span class="pre">lgtunit</span></code></a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#"><code class="docutils literal notranslate"><span class="pre">linter</span></code></a><ul>
<li class="toctree-l3"><a class="reference internal" href="#main-linter-checks">Main linter checks</a></li>
<li class="toctree-l3"><a class="reference internal" href="#help-on-linter-warnings">Help on linter warnings</a></li>
<li class="toctree-l3"><a class="reference internal" href="#extending-the-linter">Extending the linter</a></li>
<li class="toctree-l3"><a class="reference internal" href="#linting-prolog-modules">Linting Prolog modules</a></li>
<li class="toctree-l3"><a class="reference internal" href="#linting-plain-prolog-files">Linting plain Prolog files</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="make.html"><code class="docutils literal notranslate"><span class="pre">make</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="packs.html"><code class="docutils literal notranslate"><span class="pre">packs</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="ports_profiler.html"><code class="docutils literal notranslate"><span class="pre">ports_profiler</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="profiler.html"><code class="docutils literal notranslate"><span class="pre">profiler</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="tutor.html"><code class="docutils literal notranslate"><span class="pre">tutor</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="wrapper.html"><code class="docutils literal notranslate"><span class="pre">wrapper</span></code></a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../libraries/index.html">Libraries</a></li>
<li class="toctree-l1"><a class="reference internal" href="../ports/index.html">Ports</a></li>
<li class="toctree-l1"><a class="reference internal" href="../contributions/index.html">Contributions</a></li>
<li class="toctree-l1"><a class="reference internal" href="../glossary.html">Glossary</a></li>
<li class="toctree-l1"><a class="reference internal" href="../bibliography.html">Bibliography</a></li>
<li class="toctree-l1"><a class="reference internal" href="../genindex.html">Index</a></li>
</ul>

    <p class="caption"><span class="caption-text">External Contents</span></p>
    <ul>
    <li class="toctree-l1"><a class="reference internal" href="../../apis/index.html">APIs</a></li>
    <li class="toctree-l1"><a class="reference internal" href="https://logtalk.org">Logtalk website</a></li>
    <li class="toctree-l1"><a class="reference internal" href="https://github.com/LogtalkDotOrg/logtalk3">GitHub repo</a></li>
    </ul>
  
        </div>
      </div>
    </nav>

    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
          <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
          <a href="../index.html">The Logtalk Handbook</a>
      </nav>

      <div class="wy-nav-content">
        <div class="rst-content">
          <div role="navigation" aria-label="Page navigation">
  <ul class="wy-breadcrumbs">
      <li><a href="../index.html" class="icon icon-home" aria-label="Home"></a></li>
          <li class="breadcrumb-item"><a href="index.html">Developer Tools</a></li>
      <li class="breadcrumb-item active"><code class="docutils literal notranslate"><span class="pre">linter</span></code></li>
      <li class="wy-breadcrumbs-aside">
              <a href="https://github.com/LogtalkDotOrg/logtalk3/blob/master/docs/handbook/sources/devtools/linter.rst" class="fa fa-github"> Edit on GitHub</a>
      </li>
  </ul>
  <hr/>
</div>
          <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
           <div itemprop="articleBody">
             
  <section id="linter">
<span id="library-linter"></span><h1><code class="docutils literal notranslate"><span class="pre">linter</span></code><a class="headerlink" href="#linter" title="Link to this heading"></a></h1>
<p>Logtalk provides a built-in linter tool that runs automatically when
compiling and loading source files. The lint warnings are controlled by
a <a class="reference external" href="../userman/programming.html#programming-flags-lint">set of flags</a>.
The default values for these flags are defined in the backend Prolog
compiler adapter files and can be overridden from a settings file, from
a source file (e.g., a loader file), or from an entity. These flags can
be set globally using the
<a class="reference external" href="../refman/predicates/set_logtalk_flag_2.html">set_logtalk_flag/2</a>
built-in predicate. For (source file or entity) local scope, use instead
the
<a class="reference external" href="../refman/directives/set_logtalk_flag_2.html">set_logtalk_flag/2</a>
directive.</p>
<p>The linter flags can be managed as a group using the
<a class="reference external" href="../userman/programming.html#flag-linter">linter</a> meta-flag. See the
documentation for details.</p>
<p>Some lint checks are turned off by default, specially when
computationally expensive. Still, it’s a good idea to turn them on to
check your code on a regular basis (e.g., in CI/CD pipelines).</p>
<p>Note that, in some cases, the linter may generate false warnings due to
source code analysis limitations or special cases that, while valid when
intended, usually result from programming issues. When a code rewrite is
not a sensible solution to avoid the warning, the workaround is to turn
off as locally as possible the flag that controls the warning.</p>
<section id="main-linter-checks">
<h2>Main linter checks<a class="headerlink" href="#main-linter-checks" title="Link to this heading"></a></h2>
<p>Lint checks include:</p>
<ul class="simple">
<li><p>Missing directives (including scope, meta-predicate, dynamic,
discontiguous, and multifile directives)</p></li>
<li><p>Duplicated directives, clauses, and grammar rules</p></li>
<li><p>Missing predicates (unknown messages plus calls to non-declared and
non-defined predicates)</p></li>
<li><p>Calls to declared but not defined static predicates</p></li>
<li><p>Non-terminals called as predicates (instead of via the <code class="docutils literal notranslate"><span class="pre">phrase/2-3</span></code>
built-in methods)</p></li>
<li><p>Predicates called as non-terminals (instead of via the <code class="docutils literal notranslate"><span class="pre">call//1</span></code>
built-in method)</p></li>
<li><p>Non-portable predicate calls, predicate options, arithmetic function
calls, directives, flags, and flag values</p></li>
<li><p>Missing arithmetic functions (with selected backends)</p></li>
<li><p>Suspicious calls (syntactically valid calls that are likely semantic
errors; e.g. float comparisons using the standard arithmetic
comparison operators or comparing numbers using unification)</p></li>
<li><p>Deprecated directives, predicates, arithmetic functions, control
constructs, and flags</p></li>
<li><p>References to unknown entities (objects, protocols, categories, or
modules)</p></li>
<li><p>Top-level shortcuts used as directives</p></li>
<li><p>Unification goals that will succeed without binding any variables</p></li>
<li><p>Unification goals that will succeed by creating a cyclic term</p></li>
<li><p>Goals that are always true or always false</p></li>
<li><p>Trivial goal failures (due to no matching predicate clause)</p></li>
<li><p>Redefined built-in predicates</p></li>
<li><p>Redefined standard operators</p></li>
<li><p>Lambda expression unclassified variables and mixed up variables</p></li>
<li><p>Lambda expression with parameter variables used elsewhere in a clause</p></li>
<li><p>Singleton variables</p></li>
<li><p>If-then-else and soft cut control constructs without an else part</p></li>
<li><p>If-then-else and soft cut control constructs where the test is a
unification between a variable and a ground term</p></li>
<li><p>Missing parentheses around if-then-else and disjunction control
constructs in the presence of cuts in the first argument</p></li>
<li><p>Cuts in clauses for multifile predicates</p></li>
<li><p>Missing cut in repeat loops</p></li>
<li><p>Possible non-steadfast predicate definitions</p></li>
<li><p>Non-tail recursive predicate definitions</p></li>
<li><p>Redundant calls to control constructs and built-in predicates</p></li>
<li><p>Calls to all-solutions predicates with existentially qualified
variables not occurring in the qualified goal</p></li>
<li><p>Calls to all-solutions predicates with no shared variables between
template and goal</p></li>
<li><p>Calls to <code class="docutils literal notranslate"><span class="pre">bagof/3</span></code> and <code class="docutils literal notranslate"><span class="pre">setof/3</span></code> where the goal argument contains
singleton variables</p></li>
<li><p>Calls to <code class="docutils literal notranslate"><span class="pre">findall/3</span></code> used to backtrack over all solutions of a goal
without collecting them</p></li>
<li><p>Calls to <code class="docutils literal notranslate"><span class="pre">catch/3</span></code> that catch all exceptions</p></li>
<li><p>Calls to standard predicates that have more efficient alternatives</p></li>
<li><p>Unsound calls in grammar rules</p></li>
<li><p>File, entity, predicate, and variable names not following official
coding guidelines</p></li>
<li><p>Variable names that differ only on case</p></li>
<li><p>Clauses whose body is a disjunction (and that can be rewritten as
multiple clauses per coding guidelines)</p></li>
<li><p>Naked meta-variables in cut-transparent control constructs</p></li>
<li><p>Left-recursion in clauses and grammar rules</p></li>
</ul>
<p>Additional lint checks are provided by the <code class="docutils literal notranslate"><span class="pre">lgtunit</span></code>, <code class="docutils literal notranslate"><span class="pre">lgtdoc</span></code>,
<code class="docutils literal notranslate"><span class="pre">make</span></code>, and <code class="docutils literal notranslate"><span class="pre">dead_code_scanner</span></code> tools. For large projects, the data
generated by the <code class="docutils literal notranslate"><span class="pre">code_metrics</span></code> tool may also be relevant in accessing
code quality and suggesting code refactoring candidates.</p>
</section>
<section id="help-on-linter-warnings">
<h2>Help on linter warnings<a class="headerlink" href="#help-on-linter-warnings" title="Link to this heading"></a></h2>
<p>By loading the <code class="docutils literal notranslate"><span class="pre">tutor</span></code> tool, most lint warnings are expanded with
explanations and suggestions on how to fix the reported issues. See also
the <a class="reference external" href="https://logtalk.org/coding_style_guidelines.html">coding
guidelines</a> for
additional explanations.</p>
</section>
<section id="extending-the-linter">
<h2>Extending the linter<a class="headerlink" href="#extending-the-linter" title="Link to this heading"></a></h2>
<p>Experimental support for extending the linter with user-defined warnings
is available using the
<a class="reference external" href="../refman/predicates/logtalk_linter_hook_7.html">logtalk_linter_hook/7</a>
multifile hook predicate. For example, the <code class="docutils literal notranslate"><span class="pre">format</span></code> and <code class="docutils literal notranslate"><span class="pre">list</span></code>
library objects define this hook predicate to lint calls to the
<code class="docutils literal notranslate"><span class="pre">format/2-3</span></code> and <code class="docutils literal notranslate"><span class="pre">append/3</span></code> predicates for common errors and
misuses.</p>
</section>
<section id="linting-prolog-modules">
<h2>Linting Prolog modules<a class="headerlink" href="#linting-prolog-modules" title="Link to this heading"></a></h2>
<p>This tool can also be applied to Prolog modules that Logtalk is able to
compile as objects. For example, if the Prolog module file is named
<code class="docutils literal notranslate"><span class="pre">module.pl</span></code>, try:</p>
<div class="highlight-logtalk notranslate"><div class="highlight"><pre><span></span>| <span class="o">?-</span> <span class="k">logtalk_load</span>(module, [source_data(on)]).
</pre></div>
</div>
<p>Due to the lack of standardization of module systems and the abundance
of proprietary extensions, this solution is not expected to work for all
cases.</p>
</section>
<section id="linting-plain-prolog-files">
<h2>Linting plain Prolog files<a class="headerlink" href="#linting-plain-prolog-files" title="Link to this heading"></a></h2>
<p>This tool can also be applied to plain Prolog code. For example, if the
Prolog file is named <code class="docutils literal notranslate"><span class="pre">code.pl</span></code>, simply define an object including its
code:</p>
<div class="highlight-logtalk notranslate"><div class="highlight"><pre><span></span><span class="p">:- </span><span class="k">object</span>(code).
<span class="p">    :- </span><span class="k">include</span>(<span class="s">&#39;code.pl&#39;</span>).
<span class="p">:- </span><span class="k">end_object</span>.
</pre></div>
</div>
<p>Save the object to an e.g. <code class="docutils literal notranslate"><span class="pre">code.lgt</span></code> file in the same directory as
the Prolog file and then load it:</p>
<div class="highlight-logtalk notranslate"><div class="highlight"><pre><span></span>| <span class="o">?-</span> <span class="k">logtalk_load</span>(code, [source_data(on)]).
</pre></div>
</div>
<p>In alternative, use the <code class="docutils literal notranslate"><span class="pre">object_wrapper_hook</span></code> provided by the
<code class="docutils literal notranslate"><span class="pre">hook_objects</span></code> library:</p>
<div class="highlight-logtalk notranslate"><div class="highlight"><pre><span></span>| <span class="o">?-</span> <span class="k">logtalk_load</span>(hook_objects(loader)).
...

| <span class="o">?-</span> <span class="k">logtalk_load</span>(code, [hook(object_wrapper_hook), source_data(on)]).
</pre></div>
</div>
<p>With either wrapping solution, pay special attention to any compilation
warnings that may signal issues that could prevent the plain Prolog from
being fully checked when wrapped by an object.</p>
</section>
</section>


           </div>
          </div>
          <footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
        <a href="lgtunit.html" class="btn btn-neutral float-left" title="lgtunit" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
        <a href="make.html" class="btn btn-neutral float-right" title="make" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
    </div>

  <hr/>

  <div role="contentinfo">
    <p>&#169; Copyright 1998-2025, Paulo Moura.</p>
  </div>

  Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
    <a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
    provided by <a href="https://readthedocs.org">Read the Docs</a>.
   

</footer>
        </div>
      </div>
    </section>
  </div>
  <script>
      jQuery(function () {
          SphinxRtdTheme.Navigation.enable(true);
      });
  </script> 

</body>
</html>